package de.bazinga.rotw.objects.elevator;

import com.jme.math.Vector3f;
import com.jme.scene.shape.Box;
import com.jmex.game.state.GameStateManager;
import com.jmex.jbullet.collision.shapes.CollisionShape;
import com.jmex.jbullet.nodes.PhysicsNode;

import de.bazinga.rotw.collision.CollidableObjects;
import de.bazinga.rotw.game.RotwGameState;
import de.bazinga.rotw.network.BasicSyncManager;
import de.bazinga.rotw.network.Client;
import de.bazinga.rotw.network.Server;
import de.bazinga.rotw.objects.GameObject;
import de.bazinga.rotw.person.Person;
import de.bazinga.rotw.player.Player;

public class Elevator extends PhysicsNode implements GameObject {
	private static final long serialVersionUID = 1L;
	
	private PhysicsNode elevatorPhysicsNode = null;
	
	private boolean activateOnCollision = false;
	
	private ElevatorController controller = null;
	private Vector3f direction = null;
	
	public Elevator(Box elBox, Vector3f direction, float start, float maxValue, float speed, boolean activateOnCollision) {
		super(elBox, CollisionShape.ShapeTypes.BOX, 0.1f);
		
		this.setGravity(new Vector3f(0,0,0));
		this.activateOnCollision = activateOnCollision;
		this.direction = direction;

		// set this to true, so that its not affected by physics, but affects the other objects
		this.setKinematic(true);
		
		setCullHint(CullHint.Never);
		
		
		controller = new ElevatorController(this, speed, start, maxValue);
		if(activateOnCollision) controller.setActive(false);
		this.addController(controller);
	}
	
	
	public void requestInformation() {
		// Request Info?
		BasicSyncManager syncManager = 
			((RotwGameState)GameStateManager.getInstance().getChild("gameState")).getSyncManager();
		if(syncManager instanceof Client) {
			// Get Some info
			ElevatorMessage emsg = new ElevatorMessage();
			emsg.setRequestInfo(true);
			emsg.setElevatorIndex(CollidableObjects.getInstance().getObjects("gameObjects").indexOf(this));
			((Client)syncManager).getClient().sendToServer(emsg);
		}
	}

	
	public void setInvisible() {
		setCullHint(CullHint.Always);
	}

	
	public void hide() {
		
	}

	public void onCollision(Person person, boolean sendMessage) {
		if( !(person instanceof Player) || !((Player)person).hasCollision(this, false))
			return ;
		
		if(controller != null && !controller.isActive()) {
			controller.setActive(true);
			
			if(sendMessage) {
				BasicSyncManager syncManager = 
					((RotwGameState)GameStateManager.getInstance().getChild("gameState")).getSyncManager();
				
				ElevatorMessage emsg = new ElevatorMessage();
				emsg.setLocation(getLocalTranslation());
				emsg.setActive(true);
				emsg.setFactor(controller.getFactor());
				emsg.setElevatorIndex(CollidableObjects.getInstance().getObjects("gameObjects").indexOf(this));
				
				if(syncManager instanceof Server) {
					((Server)syncManager).getServer().sendToAll(emsg);
				}else{
					((Client)syncManager).getClient().sendToServer(emsg);
				}
			}
		}
	}

	@Override
	public boolean respawn() {
		// TODO Auto-generated method stub
		return false;
	}

	
	public void restart() {
		setLocalTranslation(new Vector3f(0,0,0));
		controller.setActive(true);
	}


	public boolean getActivateOnCollision() {
		return activateOnCollision;
	}



	public void setActivateOnCollision(boolean activateOnCollision) {
		this.activateOnCollision = activateOnCollision;
	}



	public Vector3f getDirection() {
		return direction;
	}



	public void setDirection(Vector3f direction) {
		this.direction = direction;
	}


	public ElevatorController getElevatorController() {
		return controller;
	}
	
	public PhysicsNode getPhysicsNode() {
		return elevatorPhysicsNode;
	}

}